package com.xiaoming.plugin.video_player;

import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.downloader.DownloaderConfig;
import com.aliyun.player.alivcplayerexpand.constants.GlobalPlayerConfig;
import com.aliyun.player.alivcplayerexpand.util.database.DatabaseManager;
import com.aliyun.player.alivcplayerexpand.util.database.LoadDbDatasListener;
import com.aliyun.player.alivcplayerexpand.util.download.AliyunDownloadInfoListener;
import com.aliyun.player.alivcplayerexpand.util.download.AliyunDownloadManager;
import com.aliyun.player.alivcplayerexpand.util.download.AliyunDownloadMediaInfo;
import com.aliyun.player.alivcplayerexpand.view.quality.QualityItem;
import com.aliyun.player.bean.ErrorCode;
import com.aliyun.player.source.VidAuth;
import com.aliyun.player.source.VidSts;
import com.aliyun.svideo.common.base.AlivcListSelectorDialogFragment;
import com.aliyun.svideo.common.utils.FileUtils;
import com.xiaoming.plugin.video_player.global.Global;
import com.xiaoming.plugin.video_player.model.Result;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.common.UniModule;

public class XmAliDownloader extends UniModule {
    /**
     * 下载管理类
     */
    private AliyunDownloadManager mAliyunDownloadManager;
    /**
     * 下载监听类
     */
    private MyDownloadInfoListener myDownloadInfoListener;
    /**
     * 下载清晰度Dialog
     */
    private AlivcListSelectorDialogFragment mAlivcListSelectorDialogFragment;

    /**
     * 是否正在加载下载信息
     */
    private boolean mIsLoadDownloadInfo = false;

    private UniJSCallback downloadCallback;

    @UniJSMethod(uiThread = true)
    public void iniSDK(JSONObject options, UniJSCallback callback) {
        if (callback == null) {
            return;
        }
        DownloaderConfig downloaderConfig = new DownloaderConfig();
        downloaderConfig.mConnectTimeoutS = 3;
        downloaderConfig.mNetworkTimeoutMs = 5000;
        if (options != null && !options.isEmpty()) {
            long mNetworkTimeoutMs = options.getLongValue("timeOut");
            if (mNetworkTimeoutMs < 5000) {
                mNetworkTimeoutMs = 5000;
            }
            int mConnectTimeoutS = options.getIntValue("retryCount");
            if (mConnectTimeoutS < 0) {
                mConnectTimeoutS = 0;
            }
            downloaderConfig.mConnectTimeoutS = mConnectTimeoutS;
            downloaderConfig.mNetworkTimeoutMs = mNetworkTimeoutMs;
            downloaderConfig.mHttpProxy = options.getString("mHttpProxy");
            downloaderConfig.mUserAgent = options.getString("mUserAgent");
            downloaderConfig.mReferrer = options.getString("mReferrer");
        }

        if (mAliyunDownloadManager == null) {
            mAliyunDownloadManager = AliyunDownloadManager.getInstance(mUniSDKInstance.getContext().getApplicationContext());
            Global.mDownloadMediaLists = new ArrayList<>();
            DatabaseManager.getInstance().createDataBase(mUniSDKInstance.getContext().getApplicationContext());
            mAliyunDownloadManager.setDownloadDir(FileUtils.getDir(mUniSDKInstance.getContext().getApplicationContext()) + GlobalPlayerConfig.DOWNLOAD_DIR_PATH);
            mAliyunDownloadManager.findDatasByDb(new LoadDbDatasListener() {
                @Override
                public void onLoadSuccess(List<AliyunDownloadMediaInfo> dataList) {
                    Global.mDownloadMediaLists.addAll(dataList);
                }
            });
        }

        mAliyunDownloadManager.setDownloaderConfig(downloaderConfig);

        //下载监听
        if (myDownloadInfoListener == null) {
            myDownloadInfoListener = new MyDownloadInfoListener(this);
            mAliyunDownloadManager.addDownloadInfoListener(myDownloadInfoListener);
        }
        callback.invoke(new Result<>(true, "初始化成功"));
    }

    @UniJSMethod(uiThread = true)
    public void getDownloadList(final UniJSCallback callback) {
        if (callback == null) {
            return;
        }
        if (mAliyunDownloadManager == null) {
            callback.invoke(new Result<>(false, "请先完成初始化"));
            return;
        }
        mAliyunDownloadManager.findDatasByDb(new LoadDbDatasListener() {
            @Override
            public void onLoadSuccess(List<AliyunDownloadMediaInfo> dataList) {
                if (Global.mDownloadMediaLists == null) {
                    Global.mDownloadMediaLists = dataList;
                } else {
                    Global.mDownloadMediaLists.clear();
                    Global.mDownloadMediaLists.addAll(dataList);
                }
                callback.invoke(new Result<>(true, "获取列表成功", dataList));
            }
        });
    }

    /**
     * 下载视频
     */
    @UniJSMethod(uiThread = true)
    public void downloadVidSts(JSONObject options, UniJSCallback callback) {
        if (callback == null) {
            return;
        }
        if (options == null || options.isEmpty()) {
            callback.invoke(new Result<>(false, "下载参数不能为空"));
            return;
        }
        if (mIsLoadDownloadInfo) {
            callback.invoke(new Result<>(false, "当前正在准备下载其他资源，请稍后"));
            return;
        }
        mIsLoadDownloadInfo = true;
        String mVid = options.getString("mVid");
        if (TextUtils.isEmpty(mVid)) {
            callback.invoke(new Result<>(false, "mVid地址不能为空"));
            return;
        }
        String mAccessKeyId = options.getString("mAccessKeyId");
        String mAccessKeySecret = options.getString("mAccessKeySecret");
        String mSecurityToken = options.getString("mSecurityToken");
        String mRegion = options.getString("mRegion");
        VidSts vidSts = new VidSts();
        vidSts.setVid(mVid);
        vidSts.setRegion(mRegion);
        vidSts.setAccessKeyId(mAccessKeyId);
        vidSts.setSecurityToken(mSecurityToken);
        vidSts.setAccessKeySecret(mAccessKeySecret);
        mAliyunDownloadManager.setmVidSts(vidSts);
        mAliyunDownloadManager.prepareDownload(vidSts);
        callback.invoke(new Result<>(true, "执行下载成功"));
    }

    /**
     * 下载视频
     */
    @UniJSMethod(uiThread = true)
    public void downloadVidAuth(JSONObject options, UniJSCallback callback) {
        if (callback == null) {
            return;
        }
        if (options == null || options.isEmpty()) {
            callback.invoke(new Result<>(false, "下载参数不能为空"));
            return;
        }
        if (mIsLoadDownloadInfo) {
            callback.invoke(new Result<>(false, "当前正在准备下载其他资源，请稍后"));
            return;
        }
        mIsLoadDownloadInfo = true;
        String mVid = options.getString("mVid");
        if (TextUtils.isEmpty(mVid)) {
            callback.invoke(new Result<>(false, "mVid地址不能为空"));
            return;
        }
        String mPlayAuth = options.getString("mPlayAuth");
        String mRegion = options.getString("mRegion");
        VidAuth vidAuth = new VidAuth();
        vidAuth.setVid(mVid);
        vidAuth.setRegion(mRegion);
        vidAuth.setPlayAuth(mPlayAuth);
        mAliyunDownloadManager.prepareDownload(vidAuth);
        callback.invoke(new Result<>(true, "执行下载成功"));
    }


    /**
     * 开始下载
     */
    @UniJSMethod(uiThread = true)
    public void startDownload(String vid, UniJSCallback callback) {
        if (callback == null) {
            return;
        }
        if (TextUtils.isEmpty(vid)) {
            callback.invoke(new Result<>(false, "vid不能为空"));
            return;
        }
        for (int i = 0; i < Global.mDownloadMediaLists.size(); i++) {
            if (vid.equals(Global.mDownloadMediaLists.get(i).getVid())) {
                if (Global.mDownloadMediaLists.get(i).getStatus() == AliyunDownloadMediaInfo.Status.Complete) {
                    callback.invoke(new Result<>(false, "任务已完成"));
                } else {
                    mAliyunDownloadManager.startDownload(Global.mDownloadMediaLists.get(i));
                    callback.invoke(new Result<>(true, "开始任务成功"));
                }
                return;
            }
        }
        callback.invoke(new Result<>(false, "未找到匹配的选项"));
    }

    /**
     * 暂停下载
     * 和 stopDownload 类似，只是不调用release
     */
    @UniJSMethod(uiThread = true)
    public void pauseDownload(String vid, UniJSCallback callback) {
        if (callback == null) {
            return;
        }
        if (TextUtils.isEmpty(vid)) {
            callback.invoke(new Result<>(false, "vid不能为空"));
            return;
        }
        for (int i = 0; i < Global.mDownloadMediaLists.size(); i++) {
            if (vid.equals(Global.mDownloadMediaLists.get(i).getVid())) {
                if (Global.mDownloadMediaLists.get(i).getStatus() == AliyunDownloadMediaInfo.Status.Complete) {
                    callback.invoke(new Result<>(false, "任务已完成"));
                } else {
                    mAliyunDownloadManager.pauseDownload(Global.mDownloadMediaLists.get(i));
                    callback.invoke(new Result<>(true, "开始任务成功"));
                }
                return;
            }
        }
        callback.invoke(new Result<>(false, "未找到匹配的选项"));
    }

    /**
     * 停止下载
     */
    @UniJSMethod(uiThread = true)
    public void stopDownload(String vid, UniJSCallback callback) {
        if (callback == null) {
            return;
        }
        if (TextUtils.isEmpty(vid)) {
            callback.invoke(new Result<>(false, "vid不能为空"));
            return;
        }
        for (int i = 0; i < Global.mDownloadMediaLists.size(); i++) {
            if (vid.equals(Global.mDownloadMediaLists.get(i).getVid())) {
                if (Global.mDownloadMediaLists.get(i).getStatus() == AliyunDownloadMediaInfo.Status.Complete) {
                    callback.invoke(new Result<>(false, "任务已完成"));
                } else {
                    mAliyunDownloadManager.stopDownload(Global.mDownloadMediaLists.get(i));
                    callback.invoke(new Result<>(true, "开始任务成功"));
                }
                return;
            }
        }
        callback.invoke(new Result<>(false, "未找到匹配的选项"));
    }

    /**
     * 删除数据
     */
    @UniJSMethod(uiThread = true)
    public void deleteItem(String vid, UniJSCallback callback) {
        if (callback == null) {
            return;
        }
        if (TextUtils.isEmpty(vid)) {
            callback.invoke(new Result<>(false, "vid不能为空"));
            return;
        }
        for (int i = 0; i < Global.mDownloadMediaLists.size(); i++) {
            if (vid.equals(Global.mDownloadMediaLists.get(i).getVid())) {
                mAliyunDownloadManager.deleteFile(Global.mDownloadMediaLists.get(i));
                callback.invoke(new Result<>(true, "删除成功"));
                return;
            }
        }
        callback.invoke(new Result<>(false, "未找到匹配的选项"));
    }

    @UniJSMethod(uiThread = true)
    public void setDownloadCallback(UniJSCallback callback) {
        this.downloadCallback = callback;
    }

    /**
     * 下载监听
     */
    private static class MyDownloadInfoListener implements AliyunDownloadInfoListener {

        private WeakReference<XmAliDownloader> weakReference;

        public MyDownloadInfoListener(XmAliDownloader aliyunPlayerSkinActivity) {
            weakReference = new WeakReference<>(aliyunPlayerSkinActivity);
        }

        @Override
        public void onPrepared(List<AliyunDownloadMediaInfo> infos) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                Collections.sort(infos, new Comparator<AliyunDownloadMediaInfo>() {
                    @Override
                    public int compare(AliyunDownloadMediaInfo mediaInfo1, AliyunDownloadMediaInfo mediaInfo2) {
                        if (mediaInfo1.getSize() > mediaInfo2.getSize()) {
                            return 1;
                        }
                        if (mediaInfo1.getSize() < mediaInfo2.getSize()) {
                            return -1;
                        }

                        if (mediaInfo1.getSize() == mediaInfo2.getSize()) {
                            return 0;
                        }
                        return 0;
                    }
                });
                aliyunPlayerSkinActivity.onDownloadPrepared(infos);
            }
        }

        @Override
        public void onAdd(AliyunDownloadMediaInfo info) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onAdd", info));
                }
            }
        }

        @Override
        public void onStart(AliyunDownloadMediaInfo info) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onStart", info));
                }
            }
        }

        @Override
        public void onProgress(AliyunDownloadMediaInfo info, int percent) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    JSONObject data = new JSONObject();
                    data.put("info", info);
                    data.put("percent", percent);
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onProgress", info));
                }
            }
        }

        @Override
        public void onStop(AliyunDownloadMediaInfo info) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onStop", info));
                }
            }
        }

        @Override
        public void onCompletion(AliyunDownloadMediaInfo info) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onCompletion", info));
                }
            }
        }

        @Override
        public void onError(AliyunDownloadMediaInfo info, ErrorCode code, String msg, String requestId) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    JSONObject data = new JSONObject();
                    data.put("info", info);
                    data.put("code", code);
                    data.put("msg", msg);
                    data.put("requestId", requestId);
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onError", data));
                }
            }

//            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
//            if (aliyunPlayerSkinActivity != null) {
//
//                if (code.getValue() == ErrorCode.ERROR_SERVER_POP_TOKEN_EXPIRED.getValue()
//                        || code.getValue() == ErrorCode.ERROR_SERVER_VOD_INVALIDAUTHINFO_EXPIRETIME.getValue()) {
//                    //鉴权过期
//                    aliyunPlayerSkinActivity.refresh(true);
//                } else {
//                    if (aliyunPlayerSkinActivity.mDownloadProgressBar != null) {
//                        aliyunPlayerSkinActivity.mDownloadProgressBar.setVisibility(View.GONE);
//                    }
//                    aliyunPlayerSkinActivity.mIsLoadDownloadInfo = false;
//                    Toast.makeText(aliyunPlayerSkinActivity, code.getValue() + " --- " + msg, Toast.LENGTH_SHORT).show();
//                }
//
//            }
        }

        @Override
        public void onWait(AliyunDownloadMediaInfo info) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onWait", info));
                }
            }
        }

        @Override
        public void onDelete(AliyunDownloadMediaInfo info) {
            if (info != null && Global.mDownloadMediaLists.size() > 0) {
                Global.mDownloadMediaLists.remove(info);
            }
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onDelete", info));
                }
            }
        }

        @Override
        public void onDeleteAll() {
            if (Global.mDownloadMediaLists.size() > 0) {
                Global.mDownloadMediaLists.clear();
            }
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onDeleteAll"));
                }
            }
        }

        @Override
        public void onFileProgress(AliyunDownloadMediaInfo info) {
            XmAliDownloader aliyunPlayerSkinActivity = weakReference.get();
            if (aliyunPlayerSkinActivity != null) {
                if (aliyunPlayerSkinActivity.downloadCallback != null) {
                    aliyunPlayerSkinActivity.downloadCallback.invoke(new Result<>(true, "onFileProgress", info));
                }
            }
        }
    }

    private void onDownloadPrepared(final List<AliyunDownloadMediaInfo> infos) {
        //数据源
        ArrayList<String> selectors = new ArrayList<>();
        for (AliyunDownloadMediaInfo info : infos) {
            selectors.add(QualityItem.getItem(mUniSDKInstance.getContext(), info.getQuality(), false).getName());
        }

//        清晰度DialogFragment
        mAlivcListSelectorDialogFragment = new AlivcListSelectorDialogFragment.Builder(((FragmentActivity) mUniSDKInstance.getContext()).getSupportFragmentManager())
                .setGravity(Gravity.BOTTOM)
                .setCancelableOutside(true)
                .setItemColor(ContextCompat.getColor(mUniSDKInstance.getContext(), R.color.alivc_common_font_red_wine))
                .setUnItemColor(ContextCompat.getColor(mUniSDKInstance.getContext(), R.color.alivc_common_font_black))
                .setNewData(selectors)
                .setDialogAnimationRes(R.style.Dialog_Animation)
                .setOnListItemSelectedListener(new AlivcListSelectorDialogFragment.OnListItemSelectedListener() {
                    private File mFile;
                    private String mPath;

                    @Override
                    public void onClick(String position) {
                        for (AliyunDownloadMediaInfo info : infos) {
                            if (QualityItem.getItem(mUniSDKInstance.getContext(), info.getQuality(), false).getName().equals(position)) {
                                if (Global.mDownloadMediaLists.contains(info)) {
                                    AliyunDownloadMediaInfo aliyunDownloadMediaInfo = Global.mDownloadMediaLists.get(Global.mDownloadMediaLists.indexOf(info));
                                    String savePath = aliyunDownloadMediaInfo.getSavePath();
                                    mPath = TextUtils.isEmpty(savePath) ? "" : savePath;
                                    mFile = new File(mPath);
                                    //手动删除本地文件后,无法再次下载问题
                                    if (mFile.exists()) {
                                        Toast.makeText(mUniSDKInstance.getContext(), mUniSDKInstance.getContext().getString(R.string.alivc_player_download_repeat_add), Toast.LENGTH_SHORT).show();
                                    } else {
                                        mAliyunDownloadManager.startDownload(info);
                                    }
                                } else {
                                    mAliyunDownloadManager.startDownload(info);
                                    if (!Global.mDownloadMediaLists.contains(info)) {
                                        Global.mDownloadMediaLists.add(0, info);
                                    }
                                }
                                break;
                            }
                        }
                    }
                })
                .create()
                .show();

        if (mAlivcListSelectorDialogFragment != null) {
            mAlivcListSelectorDialogFragment.setPosition(QualityItem.getItem(mUniSDKInstance.getContext(), "", false).getName());
        }
        //当前加载下载信息
        mIsLoadDownloadInfo = false;
    }
}
